<template>
  <div>
    <el-dialog
      :title="isEdit ? '编辑部门' : '添加部门'"
      :visible="dialogVisible"
      width="50%"
      :before-close="handleClose"
      :close-on-click-modal="false"
      :close-on-press-escape="false"
      :show-close="false"
      center
    >
      <div>
        <el-form
          ref="deptForm"
          :model="form"
          :rules="rules"
          label-width="120px"
        >
          <el-form-item label="部门名称" prop="name">
            <el-input
              v-model="form.name"
              style="width: 80%"
              placeholder="1-50个字符"
            />
          </el-form-item>
          <el-form-item label="部门编码" prop="code">
            <el-input
              v-model="form.code"
              style="width: 80%"
              placeholder="1-50个字符"
            />
          </el-form-item>
          <el-form-item label="部门负责人" prop="manager">
            <el-select
              v-model="form.manager"
              style="width: 80%"
              placeholder="请选择"
            >
              <el-option
                v-for="obj in employeeList"
                :key="obj.id"
                :value="obj.username"
              />
            </el-select>
          </el-form-item>
          <el-form-item label="部门介绍" prop="introduce">
            <el-input
              v-model="form.introduce"
              style="width: 80%"
              placeholder="1-300个字符"
              type="textarea"
              :rows="3"
            />
          </el-form-item>
        </el-form>
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="cancelFn">取 消</el-button>
        <el-button type="primary" @click="enterFn">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import {
  getEmployeeSimpleAPI,
  addDepartmentsAPI,
  getDepartDetailAPI,
  updateDepartmentsAPI
} from '@/api'
export default {
  // .sync
  // 使用:在父级.vue文件内使用子组件传入props值 :props变量名.sync='父变量名'
  // 作用: 在子组件内,this.$emit('update:props变量名',值),就可以直接给外面父变量名重新复制
  // 好处: 父级不必再特意的绑定一个事件名和方法名,然后写赋值语句
  // :visible.sync="dialogVisible"直接dialogVisible被el-dialog内部直接赋值了直接导致props变量被修改->报错
  // 解决:
  // 1. 把修改props的代码删掉(前提:你确保外面不需要这个布尔值使用)
  // 2. 如果非要修改props变量(来源于外部)
  // (1) 看看页面触发的条件,比如点击让弹窗关闭,监听点击事件,$emit回传到外面方法,让外面修改props的变量(单向数据流)
  // (2) 定义data/computed属性,初始值来自于props,页面上data/computed,子组件内,在维护一个变量
  props: {
    // 是否处于编辑状态
    isEdit: {
      type: Boolean
    },
    // 控制弹窗是否出现
    dialogVisible: {
      type: Boolean,
      default: false
    },
    // 部门的id
    parentId: {
      type: String,
      default: ''
    },
    // 用于非重复验证(全部部门数据)
    originList: {
      type: Array,
      required: true,
      //   数组/对象,props默认必须是函数形式,返回默认数组/对象
      default: (_) => []
      //   default() {
      //     return []
      //   }
    }
  },
  data() {
    // 校验部门编码是否重复
    const validCode = (rule, value, callback) => {
      // 判断是否能否找到对应的部门，如果找到了则返回该对象
      let arr = this.originList.map((item) => item.code)
      //   如果是编辑状态 需要把当前的code过滤掉
      if (this.isEdit) {
        arr = this.originList
          .filter((item) => item.id !== this.parentId)
          .map((item) => item.code)
      }
      // 如果存在该对象，则说明编码已经存在，抛出错误
      arr.includes(value)
        ? callback(new Error(`此部门编码${value}已经存在`))
        : callback()
    }
    // 校验同级部门名字是否重复
    const validateName = (rule, value, callback) => {
      // 先找到添加子部门,点击这个部门的下属
      let arr = this.originList
        .filter((item) => item.pid === this.parentId)
        .map((item) => item.name)

      // 上面是新增,下面是编辑
      if (this.isEdit) {
        // 点击的部门id,对象
        const obj = this.originList.find((item) => item.id === this.parentId)
        // 取出他的pid
        const pid = obj.pid
        // 整个列表找跟他同一个部门的那些人
        arr = this.originList
          .filter((item) => item.pid === pid && item.id !== this.parentId)
          .map((item) => item.name)
      }

      arr.includes(value)
        ? callback(new Error(`此部门名字${value}已经存在`))
        : callback()
    }
    return {
      form: {
        name: '', // 部门名称
        code: '', // 部门编码
        manager: '', // 部门管理者
        introduce: '' // 部门介绍
      },
      rules: {
        name: [
          { required: true, message: '部门名称不能为空', trigger: 'blur' },
          {
            min: 2,
            max: 10,
            message: '部门名称要求2-10个字符',
            trigger: 'blur'
          },
          { validator: validateName, trigger: 'blur' }
        ],
        code: [
          { required: true, message: '部门编码不能为空', trigger: 'blur' },
          {
            min: 1,
            max: 20,
            message: '部门编码要求1-20个字符',
            trigger: 'blur'
          },
          { validator: validCode, trigger: 'blur' }
        ],
        manager: [
          { required: true, message: '部门负责人不能为空', trigger: 'blur' }
        ],
        introduce: [
          { required: true, message: '部门介绍不能为空', trigger: 'blur' },
          {
            min: 1,
            max: 300,
            message: '部门介绍要求1-300个字符',
            trigger: 'blur'
          }
        ]
      },
      employeeList: [] // 部门负责人列表
    }
  },
  watch: {
    dialogVisible() {
      if (this.dialogVisible) {
        // 弹窗显示表示添加或者编辑
        this.getCompanyDetailFn()
      }
    }
  },
  created() {
    this.getEmployeeSimpleFn()
  },
  methods: {
    //   弹窗关闭之前执行,done()就关闭
    handleClose(done) {
      this.$confirm('确认关闭？')
        .then((_) => {
          done()
          this.$emit('update:dialogVisible', false)
        })
        .catch((_) => {})
    },
    // 取消按钮-弹窗底部按钮
    cancelFn() {
      this.$refs.deptForm.resetFields() // 表单重置
      this.$emit('update:dialogVisible', false)
    },
    // 确认按钮-弹窗底部按钮
    async enterFn() {
      this.$refs.deptForm.validate(async(valid) => {
        if (valid) {
          if (this.isEdit) {
            // const res =
            await updateDepartmentsAPI({
              ...this.form,
              id: this.parentId
            })
            // console.log(res)
            // this.$message.success(res.success)
          } else {
            // 新增
            // console.log(this.parentId)
            // const res =
            await addDepartmentsAPI({
              ...this.form,
              pid: this.parentId
            })
            // console.log(res)
            // this.$message.success(res.success)
          }
          this.$refs.deptForm.resetFields() // 表单重置

          this.$emit('update:dialogVisible', false)
          this.$emit('restList')
        } else {
          this.$message.error('表单未通过校验')
        }
      })
    },
    // 请求部门负责人 - 列表
    async getEmployeeSimpleFn() {
      const res = await getEmployeeSimpleAPI()
      // console.log(res)
      this.employeeList = res.data.data
    },
    // 请求某个部门的信息数据回显
    async getCompanyDetailFn() {
      if (this.isEdit) {
        const res = await getDepartDetailAPI(this.parentId)
        this.form = res.data.data
        // console.log(res)
      }
    }
  }
}
</script>

<style>
</style>
